package com.thinkgem.jeesite.common.utils;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

public class Util {
	public static final String notPrintStack = "notPrintStack";
	public static final String LOGIN_CHECK_CODE = "login_check_code";

	public static final String SERVICE_METHOD_KEY = "___service_method";
	public static final String CURRENT_WF_NODE_KEY = "curWfNode";
	public static final String CURRENT_WF_NODE_PROP_KEY = "curWfNodeProp";
	public static final String CURRENT_WF_ASSIGNMENT_ID_KEY = "curAssignmentId";
	public static final String CURRENT_WF_ASSIGNMENT_TYPE_KEY = "curAssignmentType";
	public static final String CURRENT_WF_STATUS = "curWfstatus";
	public static final String WF_NODE_MAP_KEY = "wfNodeMap";

	public final static String MSG_NQR = "根据您提供的条件查询不到相关信息";
	public final static String MSG_KEY = "__message";
	public final static String NULL = "<$null$>";
	public final static String FURESULT = "___FURESULT__";
	// private static Configure conf;
	public static final String SERVER_TYPE_TOMCAT = "tomcat";
	public static final String SERVER_TYPE_WEBLOGIC = "weblogic";

	/**
	 * 获取排序sql字符串
	 * 
	 * @param sortdata
	 *            排序数据，例如[grbh_asc,xm_desc]
	 * @param needOrderBy
	 *            是否要加上order by关键字
	 * @return 结果，如order by grbh asc,xm desc
	 */
	public static String getOrderSqlStr(String sortdata, boolean needOrderBy) {
		StringBuffer sql = new StringBuffer("");
		if (Util.o2s(sortdata).length() > 0) {
			sortdata = sortdata.replace('[', ' ').replace(']', ' ').trim();
			String[] sa = sortdata.split(",");
			if (sortdata.length() > 0 && sa.length > 0) {
				if (needOrderBy)
					sql.append(" order by ");
				for (String s : sa) {
					String[] ss = s.split("_");
					sql.append(ss[0]).append(" ").append(ss[1]).append(",");
				}
				if (sql.toString().endsWith(",")) {
					sql.deleteCharAt(sql.length() - 1);
				}
			}
		}
		return sql.toString();
	}

	public static boolean isNull(Object obj) {
		return null == obj || (obj instanceof String && NULL.equals(o2s(obj)));
	}

	public static String getString(HttpServletRequest request, String k) {
		return Util.o2s(request.getParameter(k));
	}

	/**
	 * 把异常对象的堆栈转换成String
	 * 
	 * @param e
	 *            异常对象
	 * @return string
	 */
	public static String printStackTrace(Throwable e) {
		String s;
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		e.printStackTrace(pw);
		s = sw.toString();
		try {
			sw.close();
		} catch (Throwable ex) {
		}
		try {
			pw.close();
		} catch (Throwable ex) {
		}
		return s;
	}

	/**
	 * 简单的把Object对象装换为String对象 如果输入参数为null则返回长度为0的字符串
	 * 如果输入参数为String，返回则把该String的两端空 字符串去掉后的字符串
	 */
	public static String o2s(Object o) {
		if (null == o) {
			return "";
		}
		if (o instanceof String) {
			return ((String) o).trim();
		}
		return o.toString().trim();
	}

	/**
	 * 把对象转换成int，失败返回0
	 * 
	 * @param o
	 *            对象
	 * @return int
	 */
	public static int o2i(Object o) {
		int r = 0;
		try {
			r = Integer.parseInt(o2s(o));
		} catch (Throwable e) {
		}
		return r;
	}

	/**
	 * 把对象转换成long，失败返回0
	 * 
	 * @param o
	 *            对象
	 * @return int
	 */
	public static long o2l(Object o) {
		long r = 0;
		try {
			r = Long.parseLong(o2s(o));
		} catch (Throwable e) {
		}
		return r;
	}

	/**
	 * 把对象转换成double，失败返回0
	 * 
	 * @param o
	 *            对象
	 * @return int
	 */
	public static double o2d(Object o) {
		double r = 0;
		try {
			// modified by hujianjun,20100708,添加金额格式化后包含逗号的支持
			String s = o2s(o);
			if (s.indexOf(',') > 0) {
				s = s.replaceAll(",", "");
			}
			r = Double.parseDouble(s);
		} catch (Throwable e) {
		}
		return r;
	}

	/**
	 * add by huijianjun, 将输入参数转换成 java.sql.Date
	 * 
	 * @param o
	 * @return
	 * @throws Exception
	 */
	public static java.sql.Date o2sqlDate(Object o) throws Exception {
		return new java.sql.Date(o2utilDate(o).getTime());
	}

	/**
	 * add by huijianjun, 将输入参数转换成 java.util.Date
	 * 
	 * @param o
	 * @return
	 * @throws Exception
	 */
	public static java.util.Date o2utilDate(Object o) throws Exception {
		if (o instanceof String) {
			String v = o2s(o);
			SimpleDateFormat sdf = null;
			if (vl(v) && v.length() == 6) { // yyyyMM
				sdf = new SimpleDateFormat("yyyyMM");
				return sdf.parse(v);
			} else if (vl(v) && v.length() == 8) { // yyyyMMdd
				sdf = new SimpleDateFormat("yyyyMMdd");
				return sdf.parse(v);
			} else if (v.indexOf('-') > 0 && v.length() == 10) { // yyyy-MM-dd
				sdf = new SimpleDateFormat("yyyy-MM-dd");
				return sdf.parse(v);
			} else if (v.indexOf('-') > 0 && v.indexOf(':') > 0 && v.length() == 19) {
				// yyyy-MM-dd HH:mm:ss
				sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				return sdf.parse(v);
			} else {
				throw new Exception("未实现的日期格式: " + o);
			}
		}
		return null;
	}

	public static double o2d(Object o, int scale) {
		if (scale < 0) {
			scale = 0;
		}
		DecimalFormat df = new DecimalFormat("0.##########");
		double t = new BigDecimal(o2d(o)).divide(new BigDecimal(1), scale, BigDecimal.ROUND_HALF_UP).doubleValue();
		String s = df.format(t).toString();
		return o2d(s);
	}

	/**
	 * 检查是否有效浮点数
	 */
	public static boolean vd(Object o) {
		try {
			Double.parseDouble(o2s(o));
			return true;
		} catch (Throwable e) {
			return false;
		}
	}

	/**
	 * 检查是否有效整数
	 */
	public static boolean vi(Object o) {
		try {
			Integer.parseInt(o2s(o));
			return true;
		} catch (Throwable e) {
			return false;
		}
	}

	/**
	 * 检查是否有效长整数
	 */
	public static boolean vl(Object o) {
		try {
			Long.parseLong(o2s(o));
			return true;
		} catch (Throwable e) {
			return false;
		}
	}

	public static double dr(double v, int scale) {
		if (scale < 0) {
			scale = 0;
		}
		return new BigDecimal(v).divide(new BigDecimal(1), scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 检查 thisClass 是否间接或者直接继承了 superClass
	 * 
	 * @param thisClass
	 *            要检查的 class
	 * @param superClass
	 *            是否被继承的 class
	 * @return boolean
	 */
	public static boolean hashSuperClass(Class thisClass, Class superClass) {
		if (thisClass == superClass) {
			return true;
		}
		Class sc = thisClass.getSuperclass();
		boolean flag = false;
		while (sc != null) {
			if (sc == superClass) {
				flag = true;
				break;
			}
			sc = sc.getSuperclass();
		}
		return flag;
	}

	/**
	 * 检查 thisClass 是否间接或者直接实现了 implementedInterface 接口
	 * 
	 * @param thisClass
	 *            要检查的class
	 * @param implementedInterface
	 *            是否被实现德接口
	 * @return boolean
	 */
	public static boolean isImplementedInterface(Class thisClass, Class implementedInterface) {
		if (thisClass == implementedInterface) {
			return true;
		}
		Class sc = thisClass;
		Class[] iis = null;
		boolean flag = false;
		while (sc != null) {
			iis = sc.getInterfaces();
			for (int i = 0; i < iis.length; i++) {
				if (iis[i] == implementedInterface) {
					flag = true;
					break;
				}
			}
			if (flag) {
				break;
			}
			sc = sc.getSuperclass();
		}
		return flag;
	}

	public static Field findField(Class ownerClass, String fieldName) {
		Field field = null;
		while (ownerClass != null) {
			try {
				field = ownerClass.getDeclaredField(fieldName);
			} catch (Exception e) {
			}
			if (field != null) {
				break;
			}
			ownerClass = ownerClass.getSuperclass();
		}
		return field;
	}

	/**
	 * 获取 ownerClass 的所有成员变量（包括被其间接或者直接继承的类的非私有成员变量）
	 * 
	 * @param ownerClass
	 *            查找的类
	 * @param findSuperClassField
	 *            是否查找其父类的成员变量
	 * @return Field 数组
	 */
	public static Field[] findFields(Class ownerClass, boolean findSuperClassField) {
		Field[] fields = null;
		ArrayList al = new ArrayList();
		while (ownerClass != null) {
			try {
				fields = ownerClass.getDeclaredFields();
				if (fields != null && fields.length > 0) {
					al.addAll(Arrays.asList(fields));
				}
			} catch (Exception e) {
				;
			}
			if (findSuperClassField) {
				ownerClass = ownerClass.getSuperclass();
			} else {
				break;
			}
		}
		return (Field[]) al.toArray(new Field[al.size()]);
	}

	/**
	 * 在 methodOwner 中查找名为 methodName，参数类型为 argTypes 的方法
	 * 
	 * @param methodOwner
	 *            要查找的类
	 * @param methodName
	 *            方法名
	 * @param argTypes
	 *            参数类型列表数组
	 * @return Method 对象
	 */
	public static Method findMethod(Class methodOwner, String methodName, Class[] argTypes) {
		Method method = null;
		do {
			if (methodOwner == null) {
				break;
			}
			Method[] methods = methodOwner.getMethods();
			Class[] gts = null;
			ArrayList list = new ArrayList();
			boolean found = false;
			Field typeField = null;
			for (int i = 0; i < methods.length; i++) {
				method = methods[i];
				gts = method.getParameterTypes();
				if (method.getName().equals(methodName) && gts.length == argTypes.length) {
					list.add(method);
					found = true;
					for (int j = 0; j < gts.length; j++) {
						if (gts[j] != argTypes[j]) {
							found = false;
							break;
						}
					}
					if (found) {
						break;
					}
				}
			}
			if (!found) {
				int fitCnt = 0;
				Iterator ir = list.iterator();
				while (ir.hasNext()) {
					method = (Method) ir.next();
					fitCnt = 0;
					gts = method.getParameterTypes();
					for (int j = 0; j < gts.length; j++) {
						found = false;
						try {
							typeField = argTypes[j].getField("TYPE");
							if (typeField != null && gts[j] == typeField.get(argTypes[j])) {
								fitCnt++;
								found = true;
							}
						} catch (Exception e) {
						}
						if (!found && (hashSuperClass(argTypes[j], gts[j])
								|| isImplementedInterface(argTypes[j], gts[j]))) {
							fitCnt++;
						}
					}
					if (fitCnt == gts.length) {
						found = true;
						break;
					}
				}
				if (!found) {
					method = null;
				}
			} else {
				list.clear();
				list = null;
			}
			if (method != null) {
				method.setAccessible(true);
			}
			/*
			 * else { method = findMethod(methodOwner.getSuperclass(),
			 * methodName, argTypes); }
			 */
		} while (false);
		return method;
	}

	public static Method findMethod(String name, Object[] args, Object target) throws Exception {
		return findMethod(name, args, target.getClass().getMethods());
	}

	public static Method findMethod(String name, Object[] args, Method[] ms) throws Exception {
		return findMethod(name, args, ms, null);
	}

	public static Method findMethod(String name, Object[] args, Method[] ms, List newArgs) throws Exception {
		Class[] ats;
		int fc;
		Class pc, ac;
		Field f;
		Method method = null;
		for (Method m : ms) {
			if (!m.getName().equals(name)) {
				continue;
			}
			ats = m.getParameterTypes();
			if (ats.length > args.length) {
				continue;
			}
			fc = 0;
			for (int i = 0; i < ats.length; i++) {
				pc = ats[i];
				if (null == args[i]) {
					fc++;
					continue;
				}
				ac = args[i].getClass();
				if (args[i] instanceof Number) {
					f = ac.getField("TYPE");
					f.setAccessible(true);
					if (f.get(ac) == pc) {
						fc++;
						continue;
					}
				}
				if (pc != ac) {
					break;
				}
				fc++;
			}
			if (fc == ats.length && fc == args.length) {
				method = m;
				break;
			}
			fc = 0;
			for (int i = 0; i < ats.length; i++) {
				pc = ats[i];
				if (null == args[i]) {
					fc++;
					continue;
				}
				ac = args[i].getClass();
				if (args[i] instanceof Number) {
					f = ac.getField("TYPE");
					f.setAccessible(true);
					if (f.get(ac) == pc) {
						fc++;
						continue;
					}
				}
				if ((pc != ac) && (!Util.isImplementedInterface(ac, pc) && !Util.hashSuperClass(ac, pc))) {
					break;
				}
				fc++;
			}
			if (fc == ats.length && fc == args.length) {
				method = m;
				break;
			}
			if (null != newArgs && ats.length - 1 == fc && Object[].class == ats[ats.length - 1]) {
				method = m;
				newArgs.clear();
				for (int j = fc; j < args.length; j++) {
					newArgs.add(args[j]);
				}
				Object[] lastArg = newArgs.toArray();
				newArgs.clear();
				for (int j = 0; j < fc; j++) {
					newArgs.add(args[j]);
				}
				newArgs.add(lastArg);
				break;
			}
		}
		return method;
	}

	public static Object invokeMethod(String name, Object[] args, Method[] ms, Object target) throws Exception {
		List list = new ArrayList();
		Method method = findMethod(name, args, ms, list);
		if (null == method) {
			throw new NoSuchMethodException(name);
		}
		method.setAccessible(true);
		try {
			if (list.size() > 0) {
				args = list.toArray();
			}
			return method.invoke(target, args);
		} catch (InvocationTargetException e) {
			throw new Exception(Util.getFirstCause(e));
		} finally {
			method.setAccessible(false);
		}
	}

	public static Object invokeMethod(String name, Object[] args, Object target) throws Exception {
		return invokeMethod(name, args, target.getClass().getMethods(), target);
	}

	/**
	 * 在 clazzz 中查找 field 对应的 get 方法
	 * 
	 * @param clazz
	 *            要查找的类
	 * @param field
	 *            field 对象
	 * @return Method 对象
	 */
	public static Method getGetter(Class clazz, Field field) {
		StringBuffer getterName = new StringBuffer();
		String fieldName = field.getName();
		String prix;
		if (fieldName.indexOf("is") == 0) {
			fieldName = fieldName.substring(2);
		}
		if (field.getType() == boolean.class) {
			getterName.append("is");
		} else {
			getterName.append("get");
		}
		getterName.append(fieldName.substring(0, 1).toUpperCase());
		getterName.append(fieldName.substring(1));
		Class[] argType = {};
		Method method = findMethod(clazz, getterName.toString(), argType);
		if (null == method) {
			fieldName = field.getName();
			getterName.setLength(0);
			getterName.append(fieldName.substring(0, 1).toUpperCase());
			getterName.append(fieldName.substring(1));
			method = findMethod(clazz, getterName.toString(), argType);
		}
		return method;
	}

	/**
	 * 在 clazzz 中查找 field 对应的 set 方法
	 * 
	 * @param clazz
	 *            要查找的类
	 * @param field
	 *            field 对象
	 * @return Method 对象
	 */
	public static Method getSetter(Class clazz, Field field) {
		StringBuffer getterName = new StringBuffer();
		String fieldName = field.getName();
		String prix;
		if (fieldName.indexOf("is") == 0) {
			fieldName = fieldName.substring(2);
		}
		getterName.append("set");
		getterName.append(fieldName.substring(0, 1).toUpperCase());
		getterName.append(fieldName.substring(1));
		Class[] argType = { field.getType() };
		Method method = findMethod(clazz, getterName.toString(), argType);
		if (null == method) {
			fieldName = field.getName();
			getterName.setLength(0);
			getterName.append("set");
			getterName.append(fieldName.substring(0, 1).toUpperCase());
			getterName.append(fieldName.substring(1));
			method = findMethod(clazz, getterName.toString(), argType);
		}
		return method;
	}

	/**
	 * 把 VO 对象转化成 Map 对象
	 * 
	 * @param vo
	 *            要转换的 VO 对象
	 * @return LinkedHashMap 对象
	 */
	public static Map<String, Object> vo2map(Object vo) {
		return vo2map(vo, "", "");
	}

	/**
	 * 把 VO 对象转化成 Map 对象
	 * 
	 * @param vo
	 *            要转换的 VO 对象
	 * @param prefix
	 *            属性名的前缀 prefix_attrName
	 * @param splitter
	 *            前缀和属性名的分隔符 prefixsplitterattrName
	 * @return LinkedHashMap 对象
	 */
	public static Map<String, Object> vo2map(Object vo, String prefix, String splitter) {
		Class clazz = vo.getClass();
		LinkedHashMap map = new LinkedHashMap();
		Field[] fields = findFields(clazz, false);
		Field f;
		Method getter;
		Object obj;
		for (int i = 0; i < fields.length; i++) {
			obj = null;
			f = fields[i];
			getter = getGetter(clazz, f);
			if (null == getter) {
				continue;
			}
			try {
				getter.setAccessible(true);
				obj = getter.invoke(vo);
			} catch (Throwable e) {
			}
			map.put(prefix + splitter + f.getName(), obj);
		}
		return map;
	}

	public static void closeInputStream(InputStream is) {
		try {
			if (null != is)
				is.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void closeOutputStream(OutputStream os) {
		try {
			if (null != os)
				os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void closeResultSet(ResultSet rs) {
		try {
			if (null != rs)
				rs.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void closeStatement(Statement stmt) {
		try {
			if (null != stmt)
				stmt.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void closePreparedStatement(PreparedStatement stmt) {
		try {
			if (null != stmt)
				stmt.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void closeConnection(Connection conn) {
		try {
			if (null != conn)
				conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void closeCallableStatement(CallableStatement stmt) {
		try {
			if (null != stmt)
				stmt.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String fit(String s, int tl, char c, char dc) {
		s = o2s(s);
		int len = s.getBytes().length;
		if (len >= tl) {
			return s;
		}
		int ml = tl - len;
		StringBuffer sb = new StringBuffer();
		if ('L' == dc) {
			for (int i = 0; i < ml; i++) {
				sb.append(c);
			}
			sb.append(s);
		} else if ('R' == dc) {
			sb.append(s);
			for (int i = 0; i < ml; i++) {
				sb.append(c);
			}
		} else {
			return s;
		}
		return sb.toString();
	}

	public static String fitL(String s, int tl, char c) {
		return fit(s, tl, c, 'L');
	}

	public static String fitR(String s, int tl, char c) {
		return fit(s, tl, c, 'R');
	}

	public static List s2list(String s, String sp) {
		s = o2s(s);
		String[] sa = s.split(sp);
		List list = new ArrayList();
		for (int i = 0; i < sa.length; i++) {
			s = o2s(sa[i]);
			if (s.length() < 1) {
				continue;
			}
			list.add(s);
		}
		return list;
	}

	public static Throwable getFirstCause(Throwable e) {
		while (null != e.getCause()) {
			e = e.getCause();
		}
		return e;
	}

	public static String getFirstCauseMessage(Throwable e) {
		String msg = o2s(getFirstCause(e).toString());
		String mh = "java.lang.Exception: ";
		String mh2 = "com.foresee.csi.workflow.util.AgileflowException: ";
		int index = msg.indexOf(mh);
		if (0 == index) {
			msg = msg.substring(mh.length());
		} else {
			index = msg.indexOf(mh2);
			if (0 == index) {
				msg = msg.substring(mh2.length());
			}
		}
		return msg;
	}

	public static String toSqlString(String s) {
		char c;
		StringBuffer sb = new StringBuffer();
		if (s == null) {
			s = "";
		}
		for (int i = 0; i < s.length(); i++) {
			c = s.charAt(i);
			if (c == '\'') {
				sb.append("''");
			} else {
				sb.append(c);
			}
		}
		return sb.toString();
	}

	public static Object beanCopy(Object dest, Object src) throws Exception {
		Map map = null;
		if (src instanceof Map) {
			map = (Map) src;
		} else {
			map = vo2map(src);
		}
		Field f = null;
		Method m;
		Object v = null;
		Class clazz = dest.getClass();
		Field[] fs = findFields(clazz, true);
		for (int i = 0; i < fs.length; i++) {
			try {
				f = fs[i];
				// modified by hujianjun,20100813,添加sql字段名与hibernate
				// vo属性名映射相等的功能
				if (!map.containsKey(f.getName()) && !map.containsKey(getKeyName(f.getName()))) {
					continue;
				}
				v = map.get(f.getName());
				if (null == v) {
					v = map.get(getKeyName(f.getName()));
				}
				if (null == v) {
					continue;
				}
				if (v instanceof String) {
					v = o2s(v);
				}
				m = getSetter(clazz, f);
				if (null == m) {
					continue;
				}
				// modified by hujianjun,20100813,添加map2vo支持
				Class cx[] = m.getParameterTypes();
				boolean ns = false; // no set value
				for (Class aCx : cx) {
					if ("java.lang.Double".equals(aCx.getName())) {
						v = o2d(v);
					} else if ("java.lang.Long".equals(aCx.getName())) {
						v = o2l(v);
					} else if ("java.lang.Integer".equals(aCx.getName())) {
						v = o2i(v);
					} else if ("java.lang.String".equals(aCx.getName())) {
						v = o2s(v);
						if (o2s(v).length() < 1)
							ns = true;
					} else if ("java.lang.BigDecimal".equals(aCx.getName())) {
						v = o2d(v);
					} else if ("java.util.Date".equals(aCx.getName())) {
						// modified by hujianjun,20100828,加入日期自动转换功能
						if (v instanceof String) {
							String s = Util.o2s(v);
							if (s.length() == 8 && vi(s)) {
								SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
								v = fmt.parse(s);
							} else if (s.length() == 6 && vi(s)) {
								SimpleDateFormat fmt = new SimpleDateFormat("yyyyMM");
								v = fmt.parse(s);
							} else if (s.length() == 10 && s.indexOf('-') > 0) {
								SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
								v = fmt.parse(s);
							} else if (s.length() == 19 && s.indexOf('-') > 0 && s.indexOf(':') > 0) {
								SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
								v = fmt.parse(s);
							} else if (s.length() == 17 && s.indexOf('-') < 0 && s.indexOf(':') > 0) {
								SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
								v = fmt.parse(s);
							}
						}
					}
				}
				if (!ns)
					m.invoke(dest, new Object[] { v });
			} catch (Exception e) {
				if (f != null) {
					System.err.println("beanCopy error fieldName: " + f.getName() + " fieldValue: " + Util.o2s(v));
				}
			}
		}
		return dest;
	}

	private static String getKeyName(String fieldName) {
		int c = fieldName.length(); // 测试字符串长度
		StringBuffer b = new StringBuffer("");
		for (int i = 0; i < c; i++) {
			Character cc = fieldName.charAt(i);
			if (Character.isUpperCase(cc)) {
				b.append("_").append(cc);
			} else {
				b.append(cc);
			}
		}
		if (b.length() > 0) {
			return b.toString().toLowerCase();
		} else {
			return fieldName;
		}
	}

	public static Object beanCopy4SrcPostfix(Object dest, Object src, String postfix, boolean onlyCopyPostfix)
			throws Exception {
		Map map = vo2map(src);
		Field f;
		Method m;
		Object v;
		Class clazz = dest.getClass();
		Field[] fs = findFields(clazz, true);
		for (int i = 0; i < fs.length; i++) {
			f = fs[i];
			String name = null;
			try {
				name = f.getName() + postfix;
			} catch (Exception e) {
			}
			if (!onlyCopyPostfix && map.containsKey(f.getName()))
				name = f.getName();
			else if (name != null && map.containsKey(name)) {
			} else
				continue;
			v = map.get(name);
			if (null == v) {
				continue;
			}
			m = getSetter(clazz, f);
			if (null == m) {
				continue;
			}
			m.invoke(dest, new Object[] { v });
		}
		return dest;
	}

	public static Object beanCopy4DestPostfix(Object dest, Object src, String postfix, boolean onlyCopyPostfix)
			throws Exception {
		Map map = vo2map(src);
		Field f;
		Method m;
		Object v;
		Class clazz = dest.getClass();
		Field[] fs = findFields(clazz, true);
		for (int i = 0; i < fs.length; i++) {
			f = fs[i];
			String name = null;
			try {
				name = f.getName().substring(0, f.getName().length() - postfix.length());
			} catch (Exception e) {
			}
			if (!onlyCopyPostfix && map.containsKey(f.getName()))
				name = f.getName();
			else if (map.containsKey(name)) {
			} else
				continue;
			v = map.get(name);
			if (null == v) {
				continue;
			}
			m = getSetter(clazz, f);
			if (null == m) {
				continue;
			}
			m.invoke(dest, new Object[] { v });
		}
		return dest;
	}

	public static Object beanCopy4DestPostfix(Object dest, Object src, String postfix) throws Exception {
		return beanCopy4DestPostfix(dest, src, postfix, false);
	}

	public static Object beanClear(Object dest) throws Exception {
		Field f;
		Method ms, mg;
		Object v;
		Class clazz = dest.getClass();
		Field[] fs = findFields(clazz, true);
		for (int i = 0; i < fs.length; i++) {
			f = fs[i];
			mg = getGetter(clazz, f);
			if (null == mg) {
				continue;
			}
			v = mg.invoke(dest, new Object[] {});
			if (null == v || !((v instanceof String && o2s(v).length() < 1) || (v instanceof Long && (Long) v < 1L)
					|| (v instanceof Integer && (Integer) v < 1))) {
				continue;
			}
			ms = getSetter(clazz, f);
			if (null == ms) {
				continue;
			}
			ms.invoke(dest, new Object[] { null });
		}
		return dest;
	}

	public static Class[] loadClass(String packageName, String className, ClassLoader cl) throws Exception {
		if (null != className) {
			ClassNotFoundException ex;
			try {
				return new Class[] { Class.forName(packageName + "." + className) };
			} catch (ClassNotFoundException e) {
				ex = e;
				try {
					return new Class[] { Class.forName(packageName + "$" + className) };
				} catch (ClassNotFoundException e1) {
					throw ex;
				}
			}
		} else {
			String path = packageName.replace(".", "/");
			if (null == cl) {
				cl = Util.class.getClassLoader();
			}
			URL url = cl.getResource(path);
			if (null == url) {
				return null;
			}
			File f = new File(url.getPath());
			if (!f.isDirectory()) {
				return null;
			}
			int index;
			String cn;
			File[] fs = f.listFiles();
			Class[] cls = new Class[fs.length];
			for (int i = 0; i < fs.length; i++) {
				cn = fs[i].getName();
				index = cn.lastIndexOf(".");
				if (index > -1) {
					cn = cn.substring(0, index);
				}
				cls[i] = loadClass(packageName, cn, cl)[0];
			}
			return cls;
		}
	}

	public static Class[] loadPackageClass(String packageName, ClassLoader cl) throws Exception {
		return loadClass(packageName, null, cl);
	}

	public static String getClassName(Class clazz) {
		if (null == clazz) {
			return "";
		}
		String s = clazz.getName();
		int i = s.lastIndexOf(".");
		if (i > -1) {
			s = s.substring(i + 1);
		}
		i = s.lastIndexOf("$");
		if (i > -1) {
			s = s.substring(i + 1);
		}
		return s;
	}

	public static String getClassName(Object obj) {
		if (null == obj) {
			return "";
		}
		if (obj instanceof Class) {
			return getClassName((Class) obj);
		}
		return getClassName(obj.getClass());
	}

	public static String getObjetListName(Class clazz) {
		return getClassName(clazz) + "List";
	}

	public static String getObjetMapName(Class clazz) {
		return getClassName(clazz) + "Map";
	}

	public static Date date8Add(String d8, int iy, int im, int id) {
		d8 = o2s(d8);
		if (8 != d8.length()) {
			return null;
		}
		Calendar c = Calendar.getInstance();
		c.set(o2i(d8.substring(0, 4)), o2i(d8.substring(4, 6)), o2i(d8.substring(6, 8)));
		c.add(Calendar.YEAR, iy);
		c.add(Calendar.MONTH, im - 1);
		c.add(Calendar.DAY_OF_MONTH, id);
		return c.getTime();
	}

	public static Object ja2js(Object obj) throws Exception {
		if (obj instanceof List) {
			List lst = (List) obj;
			StringBuffer js = new StringBuffer("[");
			for (int i = 0; i < lst.size(); i++) {
				Object o = lst.get(i);
				if (o instanceof Map) {
					Map m = (Map) o;
					Iterator it = m.keySet().iterator();
					js.append("{");
					while (it.hasNext()) {
						String k = (String) it.next();
						if (m.get(k) == null)
							continue;
						String v = (String) m.get(k);
						js.append(k).append(":'").append(v).append("'").append(",");
					}
					if (js.toString().endsWith(","))
						js.deleteCharAt(js.length() - 1);
					js.append("},");
				}
			}
			if (js.toString().endsWith(","))
				js.deleteCharAt(js.length() - 1);
			js.append("]");
			return js.toString();
		} else {
			return "";
		}
	}

	public static String ja2tv(Object obj) throws Exception {
		if (obj instanceof List) {
			List lst = (List) obj;
			StringBuffer js = new StringBuffer("[");
			for (int i = 0; i < lst.size(); i++) {
				Object o = lst.get(i);
				if (o instanceof Map) {
					Map m = (Map) o;
					Iterator it = m.keySet().iterator();
					js.append("{");
					while (it.hasNext()) {
						String k = (String) it.next();
						if (m.get(k) == null)
							continue;
						String v = (String) m.get(k);
						if (k.equals("dm"))
							js.append("v").append(":'").append(v).append("'").append(",");
						else if (k.equals("dmmc"))
							js.append("t").append(":'").append(v).append("'").append(",");
					}
					if (js.toString().endsWith(","))
						js.deleteCharAt(js.length() - 1);
					js.append("},");
				}
			}
			if (js.toString().endsWith(","))
				js.deleteCharAt(js.length() - 1);
			js.append("]");
			return js.toString();
		} else {
			return "";
		}
	}

	public static void setMercuryDefaultFilePath(String path) {
		// ConfigureFactory.setMERCURY_DEFAULT_FILE(path);
	}

	public static String getProperty(String key) {
		// try {
		// if (conf == null) {
		// conf = ConfigureFactory.getConfigure();
		// }
		// return conf.getProperty(key);
		// } catch (IOException e) {
		// e.printStackTrace();
		// return null;
		// }
		return null;
	}

	/**
	 * 是否测试环境
	 * 
	 * @return
	 */
	public static String getServerType() {
		return getProperty("server.type");
	}

	public static void main(String[] args) throws Exception {

		System.out.println(o2d("122.399", 4));
		// System.out.println(new
		// SimpleDateFormat("yyyy-MM-dd").format(date8Add("20060101", 0, 0,
		// 1000)));
		System.out.println(getKeyName("jerr"));
	}

	/**
	 * 替换字符串中的${xx}这样的变量 比如配置的sql, select * from ys_dwjbzl a,ys_grjbzl b where
	 * a.sszj like ''440606%'' and a.dwsxh=b.dwsxh and b.gmsfhm=''${gmsfhm}''
	 * 
	 * @param s
	 * @param k
	 * @param vars
	 * @return
	 */
	public static String getCleanStr(String s, String k, Map vars) {
		String kk = "${" + k + "}";
		String kkk = "\\$\\{" + k + "\\}";
		if (s.indexOf(kk) >= 0) {
			s = s.replaceAll(kkk, Util.o2s(vars.get(k)));
		}
		return s;
	}

	public static boolean isDB2(Connection conn) throws SQLException {
		String prodName = conn.getMetaData().getDatabaseProductName().toLowerCase();
		return prodName.indexOf("db2") >= 0;
	}

	public static String getXmlParamValue(List list) {
		StringBuffer s = new StringBuffer("&apos;");
		for (int i = 0; i < list.size(); i++) {
			if (i == list.size() - 1) {
				s.append(Util.o2s(list.get(i)));
				s.append("&apos;");
			} else {
				s.append(Util.o2s(list.get(i)));
				s.append("&apos;,&apos;");
			}
		}
		// String result = s.toString().replaceAll("&apos;", "'");
		return s.toString();
	}

	public static String getBrowserType(HttpServletRequest request) {
		String requestHeader = request.getHeader("User-Agent");
		return getBrowserType(requestHeader);
	}

	public static String getBrowserType(String requestHeader) {
		String browser = new String("");
		String version = new String("");
		if (requestHeader != null) {
			if ((requestHeader.indexOf("MSIE") == -1) && (requestHeader.indexOf("msie") == -1)) {
				browser = "NS";
				int verPos = requestHeader.indexOf("/");
				if (verPos != -1)
					version = requestHeader.substring(verPos + 1, verPos + 5);
			} else {
				browser = "IE";
				String tempStr = requestHeader.substring(requestHeader.indexOf("MSIE"), requestHeader.length());
				version = tempStr.substring(4, tempStr.indexOf(";"));
			}
		}
		return browser + "," + version;
	}
}
